package Filesystem;

use JIP::ToolSet;
use Exporter::Lite;
use Carp qw( croak );
use Cwd qw( cwd abs_path );
use File::Spec;
use File::Basename qw( fileparse );
use Hash::AsObject;
use English qw( -no_match_vars );

our @EXPORT_OK = qw(
    resolveCrawlerFileName
    parseCrawlerFileName
    getCrawlerOutputListing
    getFilterOutputListing
    resolveFilterOutputFileName
);

sub resolveCrawlerFileName {
    croak 'you can also use named arguments'
        if not defined( @ARG ) or scalar( @ARG ) & 1;

    my %params = @ARG;

    croak 'required parameter "host_id" not defined'
        unless defined $params{'host_id'};

    croak 'required parameter "host_ip" not defined'
        unless defined $params{'host_ip'};

    croak '"host_id" must be positive integer'
        if $params{'host_id'} !~ /^\d+$/ and $params{'host_id'} > 0;

    croak '"host_ip" must be provided in IP-address format'
        if $params{'host_ip'} !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;

    return 'ftp_'. $params{'host_id'} .'_'. $params{'host_ip'} .'.raw.txt';
}

sub parseCrawlerFileName {
    my $pathToFile = shift;

    my( $id, $ip ) = ( fileparse $pathToFile )[0] =~ m/ftp_
                                                      (\d+)
                                                      _
                                                      (\d+\.\d+\.\d+\.\d+)
                                                      \.raw\.txt
                                                      $/x;

    croak '"host_id" not defined' unless defined $id;
    croak '"host_ip" not defined' unless defined $ip;

    return Hash::AsObject->new(
        ID        => $id,
        IPAddress => $ip,
    );
}

sub getCrawlerOutputListing {
    my $pathToDirectory = shift;

    croak 'directory ('. $pathToDirectory .') not found'
        unless -d $pathToDirectory;

    return _makeListingResultSet( glob $pathToDirectory .'/*.raw.txt' );
}

sub getFilterOutputListing {
    my $pathToDirectory = shift;

    croak 'directory ('. $pathToDirectory .') not found'
        unless -d $pathToDirectory;

    return _makeListingResultSet( glob $pathToDirectory .'/*.filter.txt' );
}

sub resolveFilterOutputFileName {
    croak 'you can also use named arguments'
        if not defined( @ARG ) or scalar( @ARG ) & 1;

    my %params = @ARG;

    croak 'required parameter "ip_address" not defined'
        unless defined $params{'ip_address'};

    croak 'required parameter "content_type" not defined'
        unless defined $params{'content_type'};

    return 'ftp_'. $params{'content_type'} .'_'. $params{'ip_address'} .'.filter.txt';
}

sub _makeListingResultSet {
    my @files;

    foreach my $eachPathToFile ( @ARG ) {
        push @files, Hash::AsObject->new(
            name         => ( fileparse $eachPathToFile )[0],
            relativePath => File::Spec->abs2rel( abs_path( $eachPathToFile ), cwd() ),
            absolutePath => abs_path( $eachPathToFile ),
        );
    }

    return @files;
}

1;

__END__

=head1 NAME

Filesystem - модуль для параметризации работы с файлами которыми манипулирует система.

=head1 SYNOPSIS

    use Filesystem qw(
        resolveCrawlerFileName
        parseCrawlerFileName
        getCrawlerOutputListing
        getFilterOutputListing
        resolveFilterOutputFileName
    );

    my $fileName = resolveCrawlerFileName(
        host_id => 69,
        host_ip => '10.0.14.140',
    );

=head1 METHODS

Все функции требуют обязательного импортирования.

=head2 resolveCrawlerFileName()

Генерирует имя файла в который кроулер сохранит данные индексирования хоста.

Требует обязательного импортирования.

Получает обязательные именованные параметры:
-- host_id - идентификатор хоста (целое число)
-- host_ip - IP-адрес

Возвращает строку.

=head2 parseCrawlerFileName()

По имени файла который сгенерирован краулером (в файле находятся данные индексирования)
определяет какому хосту (IP-адрес и его ID) принадлежат данные.

Требует обязательного импортирования.

Получает обязательный неименованный параметр - имя файла.

Возвращает dataset с акцессорами ID и IPAddress.

=head2 getCrawlerOutputListing()

Формализует получение путей к файлам которые сгенерировал кроулер.

Требует обязательного импортирования.

Получает один неименованный параметр - путь к директории в которой хранятся файлы сохраненные кроулером.

Возвращает _массив_ с dataset содержащими акцессоры:
-- name         - имя файла
-- relativePath - относительный путь к файлу
-- absolutePath - абсолютный путь к файлу

=head2 getFilterOutputListing()

Формализует получение путей к файлам которые сгенерировал фильтр.

Требует обязательного импортирования.

Получает один неименованный параметр - путь к директории в которой хранятся файлы сохраненные фильтром.

Возвращает _массив_ с dataset содержащими акцессоры:
-- name         - имя файла
-- relativePath - относительный путь к файлу
-- absolutePath - абсолютный путь к файлу

=head2 resolveFilterOutputFileName()

Определяет имя файла которое сгенерирует фильтр.

Получает два обязательных именованных параметра:
-- ip_address   - IP-адрес
-- content_type - тип контента (для некой таксономии)

Возвращает строку.

=cut

